// Cell names have been changed in this file by netl_namemap on Mon Jan  3 04:00:10 UTC 2022
////////////////////////////////////////////////////////////////////////////// 
//
//  jtag_fsm.v
//
//  Generic and parameterized controller for IEEE standard Test Access Port
//  per 1149.1-2001.  It contains the FSM and IR register.  The DR registers
//  are implementation-specific and are handled externally via the capture,
//  shift, and update signals.
//
//  Original Author: Chris Jones
//  Current Owner:   Behram Minwalla
//
////////////////////////////////////////////////////////////////////////////// 
//
// Copyright (C) 2011 Synopsys, Inc.  All rights reserved.
//
// SYNOPSYS CONFIDENTIAL - This is an unpublished, proprietary work of
// Synopsys, Inc., and is fully protected under copyright and trade secret
// laws.  You may not view, use, disclose, copy, or distribute this file or
// any information contained herein except pursuant to a valid written
// license agreement. It may not be used, reproduced, or disclosed to others
// except in accordance with the terms and conditions of that agreement.
//
////////////////////////////////////////////////////////////////////////////// 
//
//    Perforce Information
//    $Author: ameer $
//    $File: //dwh/up16/main/dev/pcs_raw/dig/rtl/jtag_fsm.v $
//    $DateTime: 2013/12/17 07:13:28 $
//    $Revision: #3 $
//
////////////////////////////////////////////////////////////////////////////// 

`timescale 1ns/10fs
module dwc_e12mp_phy_x4_ns_jtag_fsm #(parameter IR_WIDTH = 8,
                  parameter IR_IDCODE= {IR_WIDTH{1'b1}}) (
// TAP interface
input  wire                trst_n,
input  wire                tck,
input  wire                tck_n,
input  wire                tms,
input  wire                tdi,
output reg                 tdo,
output reg                 tdo_en,

// Interface to internal registers
output wire [IR_WIDTH-1:0] jtag_ir,
output wire                jtag_rst,
output wire                jtag_idle,
output wire                jtag_select,
output wire                jtag_capture,
output wire                jtag_shift,
output wire                jtag_update,

// Inputs from rest of chip
input  wire                jtag_ser_out,

input  wire                scan_mode_i,
input  wire                scan_set_rst_i                                                   
);

reg [3:0]                  tap_state;
reg [3:0]                  next_state;
reg                        jtag_rst_int;

localparam                 TEST_LOGIC_RESET = 4'hF;
localparam                 RUN_TEST_IDLE = 4'hC;

localparam                 SELECT_DR  = 4'h7;
localparam                 CAPTURE_DR = 4'h6;
localparam                 SHIFT_DR   = 4'h2;
localparam                 EXIT1_DR   = 4'h1;
localparam                 PAUSE_DR   = 4'h3;
localparam                 EXIT2_DR   = 4'h0;
localparam                 UPDATE_DR  = 4'h5;

localparam                 SELECT_IR  = 4'h4;
localparam                 CAPTURE_IR = 4'hE;
localparam                 SHIFT_IR   = 4'hA;
localparam                 EXIT1_IR   = 4'h9;
localparam                 PAUSE_IR   = 4'hB;
localparam                 EXIT2_IR   = 4'h8;
localparam                 UPDATE_IR  = 4'hD;

// Next state transitions are always based on current state and the state
// of the TMS pin.  Taken from Figure 6-1 of IEEE Std 1149.1-2001.
//
// %%SYNTH:
//   set_scan_element false [get_cells $inst/tap_state_reg*]
//
always @(tap_state or tms)
  case (tap_state)
    TEST_LOGIC_RESET: next_state = tms ? TEST_LOGIC_RESET : RUN_TEST_IDLE;
    RUN_TEST_IDLE:    next_state = tms ? SELECT_DR        : RUN_TEST_IDLE;
    SELECT_DR:        next_state = tms ? SELECT_IR        : CAPTURE_DR;
    CAPTURE_DR:       next_state = tms ? EXIT1_DR         : SHIFT_DR;
    SHIFT_DR:         next_state = tms ? EXIT1_DR         : SHIFT_DR;
    EXIT1_DR:         next_state = tms ? UPDATE_DR        : PAUSE_DR;
    PAUSE_DR:         next_state = tms ? EXIT2_DR         : PAUSE_DR;
    EXIT2_DR:         next_state = tms ? UPDATE_DR        : SHIFT_DR;
    UPDATE_DR:        next_state = tms ? SELECT_DR        : RUN_TEST_IDLE;
    SELECT_IR:        next_state = tms ? TEST_LOGIC_RESET : CAPTURE_IR;
    CAPTURE_IR:       next_state = tms ? EXIT1_IR         : SHIFT_IR;
    SHIFT_IR:         next_state = tms ? EXIT1_IR         : SHIFT_IR;
    EXIT1_IR:         next_state = tms ? UPDATE_IR        : PAUSE_IR;
    PAUSE_IR:         next_state = tms ? EXIT2_IR         : PAUSE_IR;
    EXIT2_IR:         next_state = tms ? UPDATE_IR        : SHIFT_IR;
    UPDATE_IR:        next_state = tms ? SELECT_DR        : RUN_TEST_IDLE;
  endcase

// Reset can be generated asynchronously via the trst_n input pin or
// the phy_reset signal, or synchronous to falling tck if the controller
// is in the TEST_LOGIC_RESET state.
//
// Since deassertion of reset shouldn't change the state out of TLR, the
// timing on that path shouldn't matter.
//
// ASSERT: add assertion to verify this
//
// %%SYNTH:
//   set_false_path -fall -to $inst/jtag_rst_reg/preset
//   set_scan_element false [get_cells $inst/jtag_rst_reg]
//
wire jtag_tck_rst;
wire jtag_async_rst = !trst_n;

dwc_e12mp_phy_x4_ns_gen_rst_sync jtag_tck_rst_sync (
  .sync_rst        (jtag_tck_rst),
  .clk             (tck),
  .scan_mode_i     (scan_mode_i),
  .scan_set_rst_i  (scan_set_rst_i),
  .async_rst       (jtag_async_rst)
);

always @(posedge tck_n or posedge jtag_tck_rst) begin
  if (jtag_tck_rst)
    jtag_rst_int <= 1'b1;
  else
    jtag_rst_int <= (tap_state == TEST_LOGIC_RESET);
end

// Mux the scan_set_rst_i on this functional jtag_rst flop
// BM: Will need to add a atpg_cov flop on jtag_rst_int
dwc_e12mp_phy_x4_ns_gen_mux scan_jtag_rst_mux (
  .out (jtag_rst),
  .sel (scan_mode_i),
  .d0  (jtag_rst_int),
  .d1  (scan_set_rst_i)
);

// State update happens asynchronously on reset conditions or synchronously
// on rising TCK.
//
always @(posedge tck or posedge jtag_tck_rst)
  if (jtag_tck_rst)
    tap_state <= TEST_LOGIC_RESET;
  else
    tap_state <= next_state;

// Generate single-bit control signals based on the current state of the JTAG FSM
//
// jtag_idle - FSM is in idle state
//
assign jtag_idle = (tap_state == RUN_TEST_IDLE);

// jtag_select - FSM is in Select-DR state
//
assign jtag_select = (tap_state == SELECT_DR);

// ir_capture - next rising TCK edge will capture data into IR shift register
// jtag_capture - next rising TCK edge will capture data into selected DR shift register
//
wire ir_capture = (tap_state == CAPTURE_IR);
assign jtag_capture = (tap_state == CAPTURE_DR);

// ir_shift - next rising TCK edge will cause IR shift register to advance
// jtag_shift - next rising TCK edge will cause selected DR shift register to advance
//
wire ir_shift = (tap_state == SHIFT_IR);
assign jtag_shift = (tap_state == SHIFT_DR);

// ir_update - next falling TCK edge will assign IR register from IR shift register
// jtag_update - next falling TCK edge will assign DR register from DR shift register
//
wire ir_update = (tap_state == UPDATE_IR);
assign jtag_update = (tap_state == UPDATE_DR);

// Instantiate IR register
//
// %%SYNTH:
//   set_scan_element false [get_cells $inst/ir_reg/q_reg*]
//
wire ir_ser_out;
dwc_e12mp_phy_x4_ns_jtag_shdw_reg #(.WIDTH(IR_WIDTH),
                .RST_VAL(IR_IDCODE))
ir_reg (
  .q               (jtag_ir),
  .serial_out      (ir_ser_out),
  .rst             (jtag_rst),
  .clk             (tck),
  .clk_n           (tck_n),
  .capture         (ir_capture),
  .update          (ir_update),
  .shift           (ir_shift),
  .select          (1'b1),
  .capture_val     ({{IR_WIDTH-1{1'b0}},1'b1}),
  .serial_in       (tdi)
);

// Generate data and enable signals for TDO driver.  TDO staged to
// falling TCK to give 1/2-cycle hold time at external chips.
//
// %%SYNTH:
//   set_scan_element false [get_cells $inst/tdo_reg]
//   set_scan_element false [get_cells $inst/tdo_en_reg]
//
always @(posedge tck_n or posedge jtag_rst)
  if (jtag_rst)
    tdo <= 1'b0;
  else
    tdo <= ir_shift ? ir_ser_out : jtag_ser_out;

always @(posedge tck_n or posedge jtag_rst)
  if (jtag_rst)
    tdo_en <= 1'b0;
  else
    tdo_en <= ir_shift || jtag_shift;

endmodule
